#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import csv
import datetime
import re
from collections import Counter, defaultdict
from datetime import datetime, timedelta

import matplotlib.pyplot as plt
import numpy as np


class EvaluationEngine:
    """品牌危机评估引擎"""

    def __init__(self, brand_name="特斯拉", crisis_event=None):
        """
        初始化评估引擎
        
        Args:
            brand_name: 品牌名称，默认为特斯拉
            crisis_event: 危机事件描述（可选）
        """
        self.brand_name = brand_name
        self.crisis_event = crisis_event
        self.crisis_data = []  # 列表替代DataFrame
        self.response_speed_score = 0
        self.transparency_score = 0
        self.image_protection_score = 0
        self.comprehensive_score = 0

        # 自动生成模拟数据
        self.generate_mock_data()

    def generate_mock_data(self, days=30):
        """
        生成模拟数据用于测试
        
        Args:
            days: 生成数据的天数范围
            
        Returns:
            生成的数据列表
        """
        # 特斯拉的危机关键词
        crisis_keywords = ['刹车失灵', '自动驾驶事故', '电池起火', '突然降价', '维权']

        # 初始化日期和数据
        end_date = datetime.now().date()
        start_date = end_date - timedelta(days=days)
        current_date = start_date

        mock_data = []

        # 为每一天生成数据
        while current_date <= end_date:
            # 确定当天是否发生危机（20%的概率）
            is_crisis_day = np.random.random() < 0.2

            # 生成每日数据点（2-10条）
            daily_points = np.random.randint(2, 10)

            for _ in range(daily_points):
                # 70%的内容是社交媒体，20%是新闻，10%是官方声明
                data_type = np.random.choice(['social', 'news', 'official'], p=[0.7, 0.2, 0.1])

                # 如果是危机日，80%的内容与危机相关
                is_crisis_related = np.random.random() < 0.8 if is_crisis_day else np.random.random() < 0.1

                # 生成情感得分（危机相关的内容更倾向于负面）
                sentiment_score = np.random.normal(-0.7, 0.3) if is_crisis_related else np.random.normal(0.3, 0.3)
                sentiment_score = max(-1.0, min(1.0, sentiment_score))  # 限制在[-1,1]范围内

                # 生成内容标题和正文
                if data_type == 'social':
                    if is_crisis_related:
                        title = f"用户抱怨{self.brand_name}的{np.random.choice(crisis_keywords)}问题"
                        content = f"这是一条关于{self.brand_name}的{np.random.choice(crisis_keywords)}问题的社交媒体抱怨。用户表示非常不满，希望得到解决。"
                    else:
                        title = f"用户分享{self.brand_name}使用体验"
                        content = f"这是一条关于{self.brand_name}的普通社交媒体内容。用户分享了产品使用体验。"

                    source = np.random.choice(['微博用户', '知乎用户', '小红书用户', '抖音用户'])
                    platform = np.random.choice(['微博', '知乎', '小红书', '抖音'])
                    engagement = np.random.randint(10, 500)

                elif data_type == 'news':
                    if is_crisis_related:
                        title = f"媒体报道{self.brand_name}面临{np.random.choice(crisis_keywords)}危机"
                        content = f"这是一篇关于{self.brand_name}面临{np.random.choice(crisis_keywords)}危机的新闻报道。报道详细描述了事件经过和消费者反应。"
                    else:
                        title = f"媒体报道{self.brand_name}最新动态"
                        content = f"这是一篇关于{self.brand_name}的普通新闻报道。报道介绍了品牌的最新动态和市场表现。"

                    source = np.random.choice(['新华网', '人民日报', '南方周末', '财经网', '科技日报'])
                    platform = '新闻媒体'
                    engagement = np.random.randint(500, 5000)

                else:  # official
                    statement_title = f"{self.brand_name}官方声明：关于{self.crisis_event or '近期问题'}的说明"
                    statement_content = f"这是{self.brand_name}关于{self.crisis_event or '近期问题'}的官方声明。我们重视每一位用户的反馈，正在积极解决问题。我们承诺将{np.random.choice(['改进产品', '优化服务', '加强质量控制', '提供补偿'])}。"

                    # 官方声明一般是积极的响应
                    response_tone = np.random.uniform(0.1, 0.9) if is_crisis_related else sentiment_score

                    source = f"{self.brand_name}官方"
                    platform = np.random.choice(['官方网站', '官方微博'])
                    engagement = np.random.randint(1000, 5000)
                    title = statement_title
                    content = statement_content
                    sentiment_score = response_tone

                # 组织数据
                published_time = datetime.combine(
                    current_date,
                    datetime.min.time()
                ) + timedelta(hours=np.random.randint(9, 23), minutes=np.random.randint(0, 59))

                mock_data.append({
                    'data_type': data_type,
                    'title': title,
                    'content': content,
                    'source': source,
                    'published_time': published_time,
                    'date': current_date,
                    'url': f"https://example.com/{data_type}/{np.random.randint(1000, 9999)}",
                    'platform': platform,
                    'engagement': engagement,
                    'sentiment_score': sentiment_score,
                    'crisis_related': 1 if is_crisis_related else 0,
                    'crisis_keyword': np.random.choice(crisis_keywords) if is_crisis_related else "",
                    'brand_name': self.brand_name,
                    'processed_time': datetime.now()
                })

            # 移至下一天
            current_date += timedelta(days=1)

        # 保存为类属性并返回
        self.crisis_data = mock_data

        return mock_data

    def _preprocess_data(self):
        """
        预处理数据
        
        Returns:
            预处理后的数据
        """
        if not self.crisis_data:
            return []

        # 按日期排序
        self.crisis_data.sort(key=lambda x: x['published_time'])

        return self.crisis_data

    def _analyze_sentiment(self, text):
        """
        分析文本情感（简化版，使用随机值）
        
        Args:
            text: 要分析的文本
            
        Returns:
            情感得分 (-1到1之间)
        """
        # 简化版使用关键词匹配的简单逻辑
        negative_words = ['问题', '差', '糟糕', '失望', '投诉', '退款', '不满', '失败', '故障']
        positive_words = ['好', '优秀', '满意', '喜欢', '推荐', '赞', '支持', '优质', '解决']

        # 计算正面和负面词汇数量
        negative_count = sum([1 for word in negative_words if word in text])
        positive_count = sum([1 for word in positive_words if word in text])

        # 如果两者都为0，返回略微随机的中性值
        if negative_count == 0 and positive_count == 0:
            return np.random.normal(0, 0.2)

        # 计算得分
        total = negative_count + positive_count
        score = (positive_count - negative_count) / total

        # 添加一些随机性
        score += np.random.normal(0, 0.2)

        # 限制在-1到1之间
        return max(-1.0, min(1.0, score))

    def evaluate_response_speed(self):
        """
        评估响应速度
        
        Returns:
            响应速度评分 (1-5)
        """
        if not self.crisis_data:
            return 0

        # 预处理数据
        self._preprocess_data()

        # 只关注危机相关的数据
        crisis_items = [item for item in self.crisis_data if item['crisis_related'] == 1]

        if not crisis_items:
            return 3  # 返回中等分数

        # 按平台分组
        by_platform = defaultdict(list)
        for item in crisis_items:
            by_platform[item['data_type']].append(item)

        # 计算从社交媒体/新闻报道到官方回应的时间间隔
        if 'official' not in by_platform:
            self.response_speed_score = 1.5
            return self.response_speed_score

        # 获取第一条危机相关内容和第一条官方回应
        crisis_start = min([item['published_time'] for item in crisis_items
                           if item['data_type'] in ['social', 'news']],
                          default=None)

        if not crisis_start:
            self.response_speed_score = 3
            return self.response_speed_score

        first_response = min([item['published_time'] for item in by_platform['official']],
                            default=None)

        if not first_response:
            self.response_speed_score = 1.5
            return self.response_speed_score

        # 计算响应时间（小时）
        response_time = (first_response - crisis_start).total_seconds() / 3600

        # 根据响应时间评分
        if response_time <= 2:
            score = 5.0  # 极快响应（2小时内）
        elif response_time <= 6:
            score = 4.0  # 快速响应（6小时内）
        elif response_time <= 12:
            score = 3.0  # 较好响应（12小时内）
        elif response_time <= 24:
            score = 2.0  # 一般响应（24小时内）
        else:
            score = 1.0  # 缓慢响应（24小时以上）

        self.response_speed_score = score
        return score

    def evaluate_transparency(self):
        """
        评估沟通透明度
        
        Returns:
            透明度评分 (1-5)
        """
        if not self.crisis_data:
            return 0

        # 只关注官方声明
        official_statements = [item for item in self.crisis_data
                              if item['data_type'] == 'official']

        if not official_statements:
            self.transparency_score = 1.5
            return self.transparency_score

        # 透明度评估指标
        has_acknowledged_issue = False
        has_explained_cause = False
        has_proposed_solution = False
        has_given_timeline = False
        has_accepted_responsibility = False

        # 关键词和短语
        acknowledgement_terms = ['承认', '确认', '意识到', '注意到', '收到反馈', '了解到']
        cause_terms = ['原因', '导致', '因为', '由于', '分析']
        solution_terms = ['解决', '修复', '改进', '优化', '更新', '升级', '措施']
        timeline_terms = ['计划', '时间表', '将在', '预计', '天内', '小时内', '即将']
        responsibility_terms = ['责任', '负责', '问题在于我们', '我们的错', '道歉', '抱歉']

        # 检查每个官方声明
        for statement in official_statements:
            content = statement['content']

            # 检查各项指标
            if any(term in content for term in acknowledgement_terms):
                has_acknowledged_issue = True

            if any(term in content for term in cause_terms):
                has_explained_cause = True

            if any(term in content for term in solution_terms):
                has_proposed_solution = True

            if any(term in content for term in timeline_terms):
                has_given_timeline = True

            if any(term in content for term in responsibility_terms):
                has_accepted_responsibility = True

        # 计算透明度得分
        transparency_indicators = [
            has_acknowledged_issue,
            has_explained_cause,
            has_proposed_solution,
            has_given_timeline,
            has_accepted_responsibility
        ]

        # 计算满足的指标数量
        met_indicators = sum(transparency_indicators)

        # 根据满足的指标数量评分
        if met_indicators >= 5:
            score = 5.0  # 完全透明
        elif met_indicators == 4:
            score = 4.0  # 高度透明
        elif met_indicators == 3:
            score = 3.0  # 一般透明
        elif met_indicators == 2:
            score = 2.0  # 较低透明
        else:
            score = 1.0  # 不透明

        self.transparency_score = score
        return score

    def evaluate_brand_image_protection(self):
        """
        评估品牌形象保护
        
        Returns:
            品牌形象保护评分 (1-5)
        """
        if not self.crisis_data:
            return 0

        # 按日期分组计算平均情感得分
        sentiment_by_date = defaultdict(list)

        for item in self.crisis_data:
            sentiment_by_date[item['date']].append(item['sentiment_score'])

        # 计算每日平均情感得分
        daily_sentiment = {}
        for date, scores in sentiment_by_date.items():
            daily_sentiment[date] = sum(scores) / len(scores)

        # 按时间顺序排列日期
        sorted_dates = sorted(daily_sentiment.keys())

        if len(sorted_dates) < 2:
            self.image_protection_score = 3
            return self.image_protection_score

        # 获取危机前、中、后的情感得分
        crisis_start_idx = len(sorted_dates) // 3
        crisis_end_idx = crisis_start_idx * 2

        pre_crisis = sorted_dates[:crisis_start_idx]
        during_crisis = sorted_dates[crisis_start_idx:crisis_end_idx]
        post_crisis = sorted_dates[crisis_end_idx:]

        # 计算各阶段平均情感得分
        pre_sentiment = sum(daily_sentiment[date] for date in pre_crisis) / len(pre_crisis) if pre_crisis else 0
        during_sentiment = sum(daily_sentiment[date] for date in during_crisis) / len(during_crisis) if during_crisis else 0
        post_sentiment = sum(daily_sentiment[date] for date in post_crisis) / len(post_crisis) if post_crisis else 0

        # 分析情感变化
        sentiment_drop = pre_sentiment - during_sentiment
        sentiment_recovery = post_sentiment - during_sentiment

        # 评估恢复程度
        recovery_ratio = sentiment_recovery / sentiment_drop if sentiment_drop > 0 else 0

        # 根据恢复程度评分
        if recovery_ratio >= 1.0:
            score = 5.0  # 完全恢复或超越
        elif recovery_ratio >= 0.8:
            score = 4.5  # 接近完全恢复
        elif recovery_ratio >= 0.6:
            score = 4.0  # 显著恢复
        elif recovery_ratio >= 0.4:
            score = 3.5  # 良好恢复
        elif recovery_ratio >= 0.2:
            score = 3.0  # 部分恢复
        elif recovery_ratio > 0:
            score = 2.5  # 轻微恢复
        elif recovery_ratio == 0:
            score = 2.0  # 无恢复
        else:
            score = 1.5  # 持续恶化

        self.image_protection_score = score
        return score

    def generate_comprehensive_score(self):
        """
        生成综合评分
        
        Returns:
            综合评分 (1-5)
        """
        # 确保已评估各项指标
        if self.response_speed_score == 0:
            self.evaluate_response_speed()

        if self.transparency_score == 0:
            self.evaluate_transparency()

        if self.image_protection_score == 0:
            self.evaluate_brand_image_protection()

        # 加权计算综合得分
        score = (
            self.response_speed_score * 0.3 +
            self.transparency_score * 0.3 +
            self.image_protection_score * 0.4
        )

        self.comprehensive_score = round(score, 1)

        return self.comprehensive_score

    def plot_sentiment_trend(self, output_file='sentiment_trend.png'):
        """
        绘制情感趋势图
        
        Args:
            output_file: 输出文件路径
            
        Returns:
            是否成功生成图表
        """
        if not self.crisis_data:
            return False

        try:
            # 按日期分组计算平均情感得分
            sentiment_by_date = defaultdict(list)

            for item in self.crisis_data:
                date_str = item['date']
                if isinstance(date_str, str):
                    try:
                        date = datetime.strptime(date_str, '%Y-%m-%d').date()
                    except ValueError:
                        date = item['date']
                else:
                    date = item['date']
                sentiment_by_date[date].append(item['sentiment_score'])

            # 计算每日平均情感得分
            dates = sorted(sentiment_by_date.keys())
            sentiments = [sum(sentiment_by_date[date]) / len(sentiment_by_date[date]) for date in dates]

            # 创建图表
            plt.figure(figsize=(12, 6))
            plt.plot(dates, sentiments, marker='o', linestyle='-', color='blue')

            # 添加平滑趋势线
            x = np.arange(len(dates))
            z = np.polyfit(x, sentiments, 3)
            p = np.poly1d(z)
            plt.plot(dates, p(x), linestyle='--', color='red')

            # 设置图表属性
            plt.title(f"{self.brand_name} - 危机情感趋势")
            plt.xlabel("日期")
            plt.ylabel("平均情感得分")
            plt.grid(True)
            plt.xticks(rotation=45)
            plt.tight_layout()

            # 保存图表
            plt.savefig(output_file)
            plt.close()

            return True

        except Exception as e:
            return False

    def generate_evaluation_report(self, output_file='crisis_evaluation_report.csv'):
        """
        生成评估报告
        
        Args:
            output_file: 输出文件路径
            
        Returns:
            是否成功生成报告
        """
        # 确保已生成综合评分
        if self.comprehensive_score == 0:
            self.generate_comprehensive_score()

        try:
            # 生成评估结果
            evaluation_results = [
                {
                    "评估项目": "响应速度",
                    "评分": self.response_speed_score,
                    "建议": self._generate_response_speed_recommendation()
                },
                {
                    "评估项目": "沟通透明度",
                    "评分": self.transparency_score,
                    "建议": self._generate_transparency_recommendation()
                },
                {
                    "评估项目": "品牌形象保护",
                    "评分": self.image_protection_score,
                    "建议": self._generate_image_protection_recommendation()
                },
                {
                    "评估项目": "综合得分",
                    "评分": self.comprehensive_score,
                    "建议": "综合以下各项建议"
                },
                {
                    "评估项目": "总体评估",
                    "评分": self._get_overall_assessment(),
                    "建议": f"{self.brand_name}危机处理整体表现{self._get_overall_assessment()}，综合得分为{self.comprehensive_score}分（满分5分）"
                }
            ]

            # 将结果写入CSV文件
            with open(output_file, 'w', newline='', encoding='utf-8') as csvfile:
                fieldnames = ["评估项目", "评分", "建议"]
                writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
                writer.writeheader()
                for result in evaluation_results:
                    writer.writerow(result)

            return True

        except Exception as e:
            return False

    def _generate_response_speed_recommendation(self):
        """生成响应速度建议"""
        if self.response_speed_score >= 4.5:
            return f"{self.brand_name}响应速度非常快，有效控制了危机扩散"
        elif self.response_speed_score >= 3.5:
            return f"{self.brand_name}响应速度良好，基本控制了危机扩散，可进一步提高应急机制效率"
        elif self.response_speed_score >= 2.5:
            return f"{self.brand_name}响应速度一般，对危机控制有一定延迟，建议建立更高效的危机监测和响应流程"
        else:
            return f"{self.brand_name}响应速度较慢，未能及时控制危机扩散，建议全面优化危机响应机制和团队协作流程"

    def _generate_transparency_recommendation(self):
        """生成沟通透明度建议"""
        if self.transparency_score >= 4.5:
            return f"{self.brand_name}沟通透明度很高，公开了危机详情并积极承担责任，消费者信任度高"
        elif self.transparency_score >= 3.5:
            return f"{self.brand_name}沟通透明度良好，但可以提供更多危机处理细节和后续改进措施"
        elif self.transparency_score >= 2.5:
            return f"{self.brand_name}沟通透明度一般，建议增加信息公开程度，主动承认问题并详细说明解决方案"
        else:
            return f"{self.brand_name}沟通透明度不足，建议改变危机沟通策略，增加信息透明度并与用户保持持续沟通"

    def _generate_image_protection_recommendation(self):
        """生成品牌形象保护建议"""
        if self.image_protection_score >= 4.5:
            return f"{self.brand_name}形象保护效果极佳，危机后品牌形象不减反增"
        elif self.image_protection_score >= 3.5:
            return f"{self.brand_name}形象保护效果良好，危机后品牌形象基本恢复"
        elif self.image_protection_score >= 2.5:
            return f"{self.brand_name}形象保护效果一般，危机对品牌形象造成了一定影响，建议加强后续正面信息传播"
        else:
            return f"{self.brand_name}形象保护效果较差，危机严重损害了品牌形象，建议制定长期品牌形象修复计划"

    def _get_overall_assessment(self):
        """获取总体评估结果"""
        if self.comprehensive_score >= 4.5:
            return "优秀"
        elif self.comprehensive_score >= 3.5:
            return "良好"
        elif self.comprehensive_score >= 2.5:
            return "一般"
        elif self.comprehensive_score >= 1.5:
            return "较差"
        else:
            return "很差"

    def extract_key_topics(self, top_n=10):
        """
        提取关键主题
        
        Args:
            top_n: 提取的主题数量
            
        Returns:
            关键主题列表
        """
        if not self.crisis_data:
            return []

        # 筛选危机相关内容
        crisis_contents = [item['content'] for item in self.crisis_data
                          if item['crisis_related'] == 1 and 'content' in item]

        if not crisis_contents:
            return []

        try:
            # 简单的词频统计
            words = []
            stop_words = ['的', '了', '和', '是', '在', '我', '有', '就', '不', '人', '都', '一', '一个', '这个', '那个', '你', '我们', '他们']

            for content in crisis_contents:
                # 分词（简化版本，实际应使用jieba等库）
                for word in re.findall(r'\w+', content):
                    if len(word) >= 2 and word not in stop_words:
                        words.append(word)

            # 统计词频
            word_counts = Counter(words)

            # 提取高频词作为主题
            key_topics = word_counts.most_common(top_n)

            return key_topics

        except Exception as e:
            return []

if __name__ == "__main__":
    # 测试代码
    engine = EvaluationEngine("特斯拉", "刹车失灵问题")

    # 评估危机处理效果
    response_speed = engine.evaluate_response_speed()
    transparency = engine.evaluate_transparency()
    image_protection = engine.evaluate_brand_image_protection()
    comprehensive_score = engine.generate_comprehensive_score()

    print(f"响应速度评分: {response_speed}")
    print(f"沟通透明度评分: {transparency}")
    print(f"品牌形象保护评分: {image_protection}")
    print(f"综合评分: {comprehensive_score}")

    # 生成评估报告
    engine.generate_evaluation_report("特斯拉_crisis_evaluation_report.csv")

    # 绘制情感趋势图
    engine.plot_sentiment_trend("特斯拉_sentiment_trend.png")